package com.shop.cereshop.admin.redis.listener;

import com.shop.cereshop.admin.service.activity.CerePlatformActivityService;
import com.shop.cereshop.admin.service.redis.CereRedisKeyServcice;
import com.shop.cereshop.admin.service.user.CerePlatformUserService;
import com.shop.cereshop.admin.weixin.service.WxPayService;
import com.shop.cereshop.commons.constant.IntegerEnum;
import com.shop.cereshop.commons.constant.StringEnum;
import com.shop.cereshop.commons.domain.activity.CereActivitySign;
import com.shop.cereshop.commons.domain.activity.CerePlatformActivity;
import com.shop.cereshop.commons.domain.pay.CerePayLog;
import com.shop.cereshop.commons.domain.user.CerePlatformUser;
import com.shop.cereshop.commons.exception.CoBusinessException;
import com.shop.cereshop.commons.utils.EmptyUtils;
import com.shop.cereshop.commons.utils.RandomStringUtil;
import com.shop.cereshop.commons.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.Message;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.listener.KeyExpirationEventMessageListener;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RedisListener extends KeyExpirationEventMessageListener {

    private RedisTemplate<String, Object> redisTemplate;

    private CerePlatformUserService cerePlatformUserService;

    private CerePlatformActivityService cerePlatformActivityService;

    private CereRedisKeyServcice cereRedisKeyServcice;

    private WxPayService wxPayService;


    public RedisListener(RedisMessageListenerContainer listenerContainer,
                         RedisTemplate redisTemplate, CerePlatformUserService cerePlatformUserService,
                         CerePlatformActivityService cerePlatformActivityService,CereRedisKeyServcice cereRedisKeyServcice,
                         WxPayService wxPayService) {
        super(listenerContainer);
        this.redisTemplate=redisTemplate;
        this.cerePlatformUserService=cerePlatformUserService;
        this.cerePlatformActivityService=cerePlatformActivityService;
        this.cereRedisKeyServcice=cereRedisKeyServcice;
        this.wxPayService=wxPayService;
    }

    @Override
    public void onMessage(Message message, byte[] pattern) {
        // 用户做自己的业务处理即可,注意message.toString()可以获取失效的key
        System.out.println("平台端执行延时任务message="+message);
        String expiredKey = message.toString();
        String time= TimeUtils.yyMMddHHmmss();
        try {
            if(!EmptyUtils.isEmpty(expiredKey)){
                if(expiredKey.contains("-")){
                    String[] split = expiredKey.split("-");
                    String operation=split[0];
                    if(StringEnum.SEVEN_DAY_CHANGE_TOKEN.getCode().equals(operation)){
                        //替换用户token
                        changeUserToken(split[1],time);
                    }else if(StringEnum.SHOP_SIGN_IN.getCode().equals(operation)){
                        //修改当前活动状态为报名进行中
                        updateActivityState(split[1],time, IntegerEnum.ACTIVITY_SIGN_ON.getCode());
                    }else if(StringEnum.SHOP_ACTIVITY_STAY.getCode().equals(operation)){
                        //修改当前活动状态为活动待开始
                        updateActivityState(split[1],time, IntegerEnum.ACTIVITY_STAY_START.getCode());
                    }else if(StringEnum.SHOP_ACTIVITY_IN.getCode().equals(operation)){
                        //修改当前活动状态为活动进行中
                        updateActivityState(split[1],time, IntegerEnum.ACTIVITY_START.getCode());
                    }else if(StringEnum.SHOP_ACTIVITY_END.getCode().equals(operation)){
                        //修改当前活动状态为活动已结束
                        updateActivityState(split[1],time, IntegerEnum.ACTIVITY_END.getCode());
                    }else if(StringEnum.THREE_DAY_REFUND_BOND.getCode().equals(operation)){
                        //报名失败3天后自动退款
                        signError(split[1]);
                    }else if(StringEnum.ACTIVITY_END_FIFTEAN_REFUND_BOND.getCode().equals(operation)){
                        //活动结束15天后自动退款至商家微信
                        signRefund(split[1]);
                    }
                    //删除失效的key
                    redisTemplate.delete(expiredKey);
                    //删除redis延时任务记录
                    cereRedisKeyServcice.deleteByKey(expiredKey);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    private void signRefund(String signId) throws CoBusinessException,Exception{
        //根据报名id查询报名数据
        CereActivitySign activitySign=cerePlatformActivityService.findSign(signId);
        if(activitySign!=null){
            //查询保证金支付流水,自动退保证金
            CerePayLog bondPayLog = cerePlatformActivityService.findBondPayLog("BZJ-" + activitySign.getShopId() + "-" + activitySign.getActivityId());
            if(bondPayLog!=null) {
                wxPayService.refundBond(bondPayLog.getTransactionId(), bondPayLog.getOutRefundNo(), bondPayLog.getTotalFee(), bondPayLog.getTotalFee());
            }
        }
    }

    private void signError(String signId) throws CoBusinessException,Exception{
        //根据报名id查询报名数据
        CereActivitySign activitySign=cerePlatformActivityService.findSign(signId);
        if(activitySign!=null){
            //根据店铺id和活动id查询除了当前报名数据以外是否有其他报名未失败的数据
            CereActivitySign checkSignError=cerePlatformActivityService.checkSignError(activitySign);
            if(checkSignError==null){
                //查询保证金支付流水,自动退保证金
                CerePayLog bondPayLog = cerePlatformActivityService.findBondPayLog("BZJ-" + activitySign.getShopId() + "-" + activitySign.getActivityId());
                if(bondPayLog!=null){
                    wxPayService.refundBond(bondPayLog.getTransactionId(),bondPayLog.getOutRefundNo(),bondPayLog.getTotalFee(),bondPayLog.getTotalFee());
                    //查询所有报名数据,清空延时任务
                    List<Long> ids=cerePlatformActivityService.findSignIdsByShopIdAndActivityId(activitySign.getShopId(),activitySign.getActivityId());
                    if(!EmptyUtils.isEmpty(ids)){
                        for (Long id:ids) {
                            redisTemplate.delete(StringEnum.THREE_DAY_REFUND_BOND.getCode()+"-"+id);
                            //同步删除redis延时任务记录
                            cereRedisKeyServcice.deleteByKey(StringEnum.THREE_DAY_REFUND_BOND.getCode()+"-"+id);
                        }
                    }
                }
            }
        }
    }

    private void updateActivityState(String id, String time, Integer state) throws CoBusinessException,Exception{
        Long activityId = Long.parseLong(id);
        //查询活动数据
        CerePlatformActivity cerePlatformActivity=cerePlatformActivityService.findById(activityId);
        cerePlatformActivity.setActivityId(activityId);
        cerePlatformActivity.setUpdateTime(time);
        cerePlatformActivity.setState(state);
        cerePlatformActivityService.updateActivity(cerePlatformActivity);
        if(IntegerEnum.ACTIVITY_SIGN_ON.getCode().equals(state)){
            //如果当前是修改状态为报名进行中,新增延时任务修改状态为活动待开始
            //过期时间为报名结束时间-当前时间
            redisTemplate.opsForValue().set(StringEnum.SHOP_ACTIVITY_STAY.getCode()+"-"+cerePlatformActivity.getActivityId(),1,
                    TimeUtils.getCountDownByTime(TimeUtils.yyMMddHHmmss(),cerePlatformActivity.getSignEndTime()), TimeUnit.MILLISECONDS);
            //新增redis过期key记录
            cereRedisKeyServcice.add(StringEnum.SHOP_ACTIVITY_STAY.getCode()+"-"+cerePlatformActivity.getActivityId(),cerePlatformActivity.getSignEndTime());
        }else if(IntegerEnum.ACTIVITY_STAY_START.getCode().equals(state)){
            //如果当前是修改状态为活动待开始,新增延时任务修改状态为活动进行中
            //过期时间为活动开始时间-当前时间
            redisTemplate.opsForValue().set(StringEnum.SHOP_ACTIVITY_IN.getCode()+"-"+cerePlatformActivity.getActivityId(),1,
                    TimeUtils.getCountDownByTime(TimeUtils.yyMMddHHmmss(),cerePlatformActivity.getActivityStartTime()),TimeUnit.MILLISECONDS);
            //新增redis过期key记录
            cereRedisKeyServcice.add(StringEnum.SHOP_ACTIVITY_IN.getCode()+"-"+cerePlatformActivity.getActivityId(),cerePlatformActivity.getActivityStartTime());
        }else if(IntegerEnum.ACTIVITY_START.getCode().equals(state)){
            //如果当前是修改状态为活动进行中,新增延时任务修改状态为活动已结束
            //过期时间为活动结束时间-当前时间
            redisTemplate.opsForValue().set(StringEnum.SHOP_ACTIVITY_END.getCode()+"-"+cerePlatformActivity.getActivityId(),1,
                    TimeUtils.getCountDownByTime(TimeUtils.yyMMddHHmmss(),cerePlatformActivity.getActivityEndTime()),TimeUnit.MILLISECONDS);
            //新增redis过期key记录
            cereRedisKeyServcice.add(StringEnum.SHOP_ACTIVITY_END.getCode()+"-"+cerePlatformActivity.getActivityId(),cerePlatformActivity.getActivityEndTime());
        }
        //查询活动是否需要保证金
        Integer ifBond=cerePlatformActivityService.findIfBond(activityId);
        if(IntegerEnum.ACTIVITY_END.getCode().equals(state)&&IntegerEnum.YES.getCode().equals(ifBond)){
            //如果活动已结束
            //新增延时任务15天后所有参与该活动的商家自动退还保证金
            List<CereActivitySign> list=cerePlatformActivityService.findByActivity(activityId);
            if(!EmptyUtils.isEmpty(list)){
                for (CereActivitySign activitySign:list) {
                    redisTemplate.opsForValue().set(StringEnum.ACTIVITY_END_FIFTEAN_REFUND_BOND.getCode()+"-"+activitySign.getSignId(),1,
                            TimeUtils.getCountDownByTime(time,TimeUtils.getMoreDayAfter(time,15)),TimeUnit.MILLISECONDS);
                    //新增延时任务记录
                    cereRedisKeyServcice.add(StringEnum.ACTIVITY_END_FIFTEAN_REFUND_BOND.getCode()+"-"+activitySign.getSignId(),
                            TimeUtils.getMoreDayAfter(time,15));
                }
            }
        }else if(IntegerEnum.ACTIVITY_START.getCode().equals(state)){
            //如果活动刚开始,未审核或者审核失败都视为报名失败,自动退保证金
            List<CereActivitySign> signs=cerePlatformActivityService.findErrorSign(activityId);
            if(!EmptyUtils.isEmpty(signs)){
                //更新报名状态为报名失败
                cerePlatformActivityService.updateSignStateError(signs);
                if(IntegerEnum.YES.getCode().equals(ifBond)){
                    //退还保证金
                    for (CereActivitySign sign:signs) {
                        //查询保证金支付流水,自动退保证金
                        CerePayLog bondPayLog = cerePlatformActivityService.findBondPayLog("BZJ-" + sign.getShopId() + "-" + sign.getActivityId());
                        if(bondPayLog!=null){
                            wxPayService.refundBond(bondPayLog.getTransactionId(),bondPayLog.getOutRefundNo(),bondPayLog.getTotalFee(),bondPayLog.getTotalFee());
                        }
                    }
                }
            }
        }
    }

    private void changeUserToken(String platformUserId, String time) throws CoBusinessException {
        CerePlatformUser cerePlatformUser=new CerePlatformUser();
        cerePlatformUser.setPlatformUserId(Long.parseLong(platformUserId));
        cerePlatformUser.setUpdateTime(time);
        cerePlatformUser.setToken(RandomStringUtil.getRandomCode(128,0));
        cerePlatformUserService.updateToken(cerePlatformUser);
    }
}
